package com.baidunewmusic;

import java.net.HttpURLConnection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
import android.graphics.Bitmap;
import android.os.Handler;
import android.widget.ImageView;

public class ImageLoader {
	static private ImageLoader _instance;
	static public ImageLoader getInstance() {
		if (_instance == null) {
			_instance = new ImageLoader();
		}
		return _instance;
	}

	private HashMap<String , Bitmap> _urlToBitmap;
	private Queue<Group> _queue;
	private DownloadThread _thread;
	private Bitmap _missing;
	private boolean _busy;

    /**
     * Constructor
     */
	private ImageLoader () {
		_urlToBitmap = new HashMap<String , Bitmap>();
		_queue = new LinkedList<Group>();
		_busy = false;
	}

	public Bitmap get(String url) {
		return _urlToBitmap.get(url);
	}

	public void load(ImageView image, String url) {
		load(image, url, false);
	}

	public void load(ImageView image, String url, boolean cache) {
		if (_urlToBitmap.get(url) != null) {
			if(image!=null) {
				Bitmap bm = _urlToBitmap.get(url);
				bm = ImageUtilities.scaleAndFrame(bm, 250, 120);
				image.setImageBitmap(bm);
				//group.bitmap = 
			}
		} else {
			image.setImageBitmap(null);
			queue(image, url, cache);
		}
	}

	public void queue(ImageView image, String url, boolean cache) {
		Iterator<Group>  it = _queue.iterator();
		if (image!=null) {
			while (it.hasNext()) {
				if (it.next().image.equals(image)) {
					it.remove();
					break;
				}
			}
		} else if (url!=null) {
			while (it.hasNext()) {
				if (it.next().url.equals(url)) {
					it.remove();
					break;
				}
			}
		}
		_queue.add(new Group(image, url, null, cache));
		loadNext();
	}

	public void clearQueue() {
		_queue = new LinkedList<Group>();
	}

	public void clearCache() {
		_urlToBitmap = new HashMap<String , Bitmap>();
	}

	public void cancel() {
		clearQueue();
		if ( _thread != null ) {
			_thread.disconnect();
			_thread = null;
		}
	}

	public void setMissingBitmap(Bitmap bitmap) {
		_missing = bitmap;
	}

	private void loadNext() {
		Iterator<Group> it = _queue.iterator();
		if (!_busy && it.hasNext() ) {
			_busy = true;
			Group group = it.next();
			it.remove();
			// double check image availability
			if (_urlToBitmap.get(group.url) != null) {
				if (group.image!=null) {
					Bitmap bm = _urlToBitmap.get(group.url);
					bm = ImageUtilities.scaleAndFrame(bm, 250, 120);
					//group.image.setImageBitmap(_urlToBitmap.get(group.url));
					group.image.setImageBitmap(bm);
					
				}
				_busy = false;
				loadNext();
			} else {
				_thread = new DownloadThread(group);
				_thread.start();
			}
		}
	}

	private void onLoad() {
		if (_thread != null) {
			Group group = _thread.group;
			if (group.bitmap != null) {
				if (group.cache) {
					_urlToBitmap.put(group.url, group.bitmap);
				}
				if (group.image != null) {
					//group.image.setImageBitmap(group.bitmap);
					group.bitmap = ImageUtilities.scaleAndFrame(group.bitmap, 250, 120);
					group.image.setImageBitmap(group.bitmap);
					//group.image.setImageBitmap(ImageUtilities.makeReflection(group.bitmap));
//					group.image.setAlpha(150);
					//group.image.setColorFilter(0x101010, PorterDuff.Mode.SRC_ATOP);
					
				}
			} else if (_missing != null) {
				if (group.image != null) {
					group.image.setImageBitmap(_missing);
				}
			}
		}
		_thread = null;
		_busy = false;
		loadNext();
	}

	private class Group {
		public Group(ImageView image, String url, Bitmap bitmap, boolean cache) {
			this.image = image;
			this.url = url;
			this.bitmap = bitmap;
			this.cache = cache;
		}
		public ImageView image;
		public String url;
		public Bitmap bitmap;
		public boolean cache;

	}

	private class DownloadThread extends Thread {
		final Handler threadHandler = new Handler();
	    final Runnable threadCallback = new Runnable() {
	        public void run() {
	        	onLoad();
	        }
	    };
		private HttpURLConnection _conn;
		public Group group;
		public DownloadThread(Group group) {
			this.group = group;
		}

		@Override
		public void run() {
			
			group.bitmap = BitmapUtils.loadBitmap(group.url);
			
			threadHandler.post(threadCallback);
		}

		public void disconnect() {
			if (_conn != null) {
				_conn.disconnect();
			}
		}
	}
}
